package models

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"strconv"
	"time"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
)

// 账号信息表
type TAccount struct {
	Uin        uint      `orm:"pk;auto;column(uin)"`
	DeviceId   string    `orm:"size(64);index;column(deviceId)"`
	Passwd     string    `orm:"size(64)"`
	Nick       string    `orm:"size(16);default();index"`
	UserId     uint      `orm:"column(userId)"`
	Cards      uint      `orm:"default(0)"`
	OpenId     string    `orm:"size(64);column(openId)"`
	Unionid    string    `orm:"size(64)"`
	HeadUrl    string    `orm:"size(200);column(headUrl)"`
	Sex        uint      `orm:"default(0)"`
	Country    string    `orm:"size(10)"`
	Province   string    `orm:"size(10)"`
	City       string    `orm:"size(10)"`
	CreateTime time.Time `orm:"auto_now_add;type(datetime)"`
	UpdateTime time.Time `orm:"auto_now;type(datetime)"`
}

// 登录日志表
type TLogLogin struct {
	Id         uint64 `orm:"pk;auto"`
	Uin        uint
	OpTime     time.Time `orm:"auto_now_add;type(datetime)"`
	OpIp       string    `orm:"size(32)"`
	GeoPoint   string    `orm:"size(32)"`
	LogOutTime time.Time `orm:"auto_now;type(datetime);column(logout_time)"`
	Session    string    `orm:"size(32)"`
}

// 对局日志表
type TLogPlay struct {
	Id         uint64    `orm:"pk;auto"`
	Uin        uint      `orm:"index"`
	RoomNo     uint      `orm:"column(roomNo)"`
	Round      uint      `orm:"default(0);column(round)"`
	RoundId    uint      `orm:"default(0);column(roundId)"`
	Head       int       `orm:"default(0)"`
	Middle     int       `orm:"default(0)"`
	Tail       int       `orm:"default(0)"`
	BattleTime time.Time `orm:"type(datetime);column(battleTime)"`
	Score      int       `orm:"default(0)"`
}

// 设置引擎为 INNODB
func (u *TAccount) TableEngine() string {
	return "INNODB"
}

func (u *TLogLogin) TableEngine() string {
	return "INNODB"
}

func (u *TLogPlay) TableEngine() string {
	return "INNODB"
}

// 设置表名
func (u *TAccount) TableName() string {
	return "tAccount"
}

func (u *TLogLogin) TableName() string {
	return "tLogLogin"
}

func (u *TLogPlay) TableName() string {
	return "tLogPlay"
}

// 多字段索引
func (u *TLogLogin) TableIndex() [][]string {
	return [][]string{
		[]string{"Uin", "OpTime"},
	}
}

// 玩家登录信息
type UserInfo struct {
	Nick     string `json:"nick"`
	OpenId   string `json:"openId"`
	HeadUrl  string `json:"headUrl"`
	Sex      string `json:"sex"`
	Country  string `json:"country"`
	Province string `json:"province"`
	City     string `json:"city"`
	Unionid  string `json:"unionid"`
	Version  string `json:"version"`
	GeoPoint string `json:"geoPoint"`
}

// 玩家登录游服信息
type GameInfo struct {
	Server  string `json:"server"`
	Port    string `json:"port"`
	UserId  int    `json:"userId"`
	Sex     string `json:"sex"`
	Session string `json:"session"`
}

func init() {
	orm.RegisterDriver("mysql", orm.DRMySQL)

	user := beego.AppConfig.String("mysqluser")
	pass := beego.AppConfig.String("mysqlpass")
	host := beego.AppConfig.String("mysqlurls")
	db := beego.AppConfig.String("mysqldb")
	orm.RegisterDataBase("default", "mysql", user+":"+pass+"@tcp("+host+")/"+db+"?charset=utf8&loc=Asia%2FShanghai")

	orm.SetMaxIdleConns("default", 100)
	orm.SetMaxOpenConns("default", 100)

	orm.RegisterModel(new(TAccount), new(TLogLogin), new(TLogPlay), new(TLogOrder), new(TRechargeItem), new(TRechargeItemIos), new(TLogRoomSet))

	createItem()
}

// 创建玩家ID
func GetAccount(user UserInfo) uint {
	o := orm.NewOrm()
	sex, _ := strconv.ParseInt(user.Sex, 10, 64)
	if user.Unionid == "" {
		user.Unionid = user.OpenId
	}
	account := TAccount{
		OpenId:   user.OpenId,
		Unionid:  user.Unionid,
		HeadUrl:  user.HeadUrl,
		Sex:      uint(sex),
		Country:  user.Country,
		Province: user.Province,
		City:     user.City,
		Nick:     user.Nick,
	}
	// 三个返回参数依次为：是否新创建的，对象 Id 值，错误
	var uin uint
	if created, id, err := o.ReadOrCreate(&account, "Unionid"); err == nil {
		if created {
			account.Cards = 20
			o.Update(&account)
			beego.Info("New Insert an user. Id:", id, user)
		} else {
			_, err := o.QueryTable(new(TAccount)).Filter("uin", id).Update(orm.Params{
				"Nick":       user.Nick,
				"UpdateTime": time.Now(),
			})
			beego.Info("Get an user. Id:", id, user.Nick, err)
		}
		uin = uint(id)
	} else {
		beego.Info("err ", err)
	}

	return uin
}

// 记录登录日志
func LogLogin(login TLogLogin) {
	o := orm.NewOrm()

	id, err := o.Insert(&login)
	if err != nil {
		beego.Debug("error ", err)
	}
	beego.Info("logId ", id)
}

// 创建订单号
func CreateSession(login TLogLogin) string {
	t := time.Now()
	beego.Info(" date = ", t)

	var buffer bytes.Buffer
	buffer.WriteString(login.OpIp)
	buffer.WriteString("quwan")
	buffer.WriteString(strconv.FormatInt(int64(login.Uin), 10))
	buffer.WriteString(strconv.FormatInt(t.Unix(), 10))
	s := buffer.String()
	beego.Info("str = ", s)

	md5Ctx := md5.New()
	//io.WriteString(md5Ctx, s)
	md5Ctx.Write([]byte(s))
	cipherStr := hex.EncodeToString(md5Ctx.Sum(nil))
	beego.Info("md5 = ", cipherStr)

	return cipherStr
}

// 创建物品ID
func createItem() {
	o := orm.NewOrm()
	itemIos := []TRechargeItemIos{{Id: 1002, Name: "房卡4张", Money: 6, Count: 4}, {Id: 1003, Name: "房卡20张", Money: 30, Count: 20}, {Id: 1004, Name: "房卡66张", Money: 98, Count: 66}, {Id: 1005, Name: "房卡220张", Money: 328, Count: 220}}
	successNumsIos, err := o.InsertMulti(6, itemIos)
	if err != nil {
		beego.Debug("err = ", err)
	}
	item := []TRechargeItem{{Id: 2, Name: "房卡20张", Money: 3000, Count: 20}, {Id: 3, Name: "房卡60张", Money: 9000, Count: 60}, {Id: 4, Name: "房卡100张", Money: 15000, Count: 100}, {Id: 5, Name: "房卡200张", Money: 30000, Count: 200}}
	successNums, err := o.InsertMulti(6, item)
	if err != nil {
		beego.Debug("err = ", err)
	}
	beego.Info("success IOS = ", successNumsIos)
	beego.Info("success = ", successNums)
	//// 三个返回参数依次为：是否新创建的，对象 Id 值，错误
	//if created, id, err := o.ReadOrCreate(&item, "Id"); err == nil {
	//	if created {
	//		beego.Info("New Insert an item. Id:", id)
	//	} else {
	//		beego.Info("Get an item. Id:", id)
	//	}
	//} else {
	//	beego.Info("err ",err)
	//}
}
